#include<iostream>
#include<fstream>
#include<stdio.h>

#include"../include/Mymath.h"

using namespace std;

class binomial
{
     float N;
	long double N_fact;
	//int n;
	float p;
	float q;
	
     public :
          binomial( float N_tmp=0.0, float p_tmp=0.0, float q_tmp=0.0 )
		{
		     N = N_tmp;
			//n = n_tmp;
			p = p_tmp;
			q = q_tmp;
			
			N_fact = factorial(N);
		}
		
		long double term(float x)
		{
		     if( x>=0 && x<=N )
		         return( ( N_fact / ( factorial(x) * factorial(N-x) ) ) * \
			          ( pow(p,x) * pow(q,N-x) )  );
			else 
			     {
			     cout<<"\n x is moving out of range\n";
				exit(0);
				}
		}
		
		void create_plot_file(char *filename)
		{
		     ofstream dataout(filename,ios::out);
			
			if(dataout.good()) 
				cout<<"\nThe output file has been opened without problems\n";
			else 
			{
				cout<<"\nAn Error has happend on opening the output file\n";
				exit(1);
			}
			
               double max_y=0.0;
			long double tmp_y;
			
			for(float i=0.0; i<N; i+=1.0)
			{
			     tmp_y = term(i);
			     if(max_y<tmp_y)
				     max_y=tmp_y;
			     dataout<<i<<" "<<tmp_y<<"\n";
			}
			
			cout<<"\nTemporary Graph data is written on the output file\n";
			dataout.close();
			
		}

          void create_plot_p2N_file(float factor,char *filename)
		{
		     float N_tmp,N_fact_tmp;
			
			N_tmp = N;
			N_fact_tmp = N_fact;
			
			ofstream dataout(filename,ios::out);
			
			if(dataout.good()) 
				cout<<"\nThe output file has been opened without problems\n";
			else 
			{
				cout<<"\nAn Error has happend on opening the output file\n";
				exit(1);
			}
			
               double max_y=0.0;
			long double tmp_y;
			
			for(float i=N_tmp; i<(N_tmp+(20*factor)); i+=factor)
			{
			     N = i;
				N_fact = factorial(N);
				
			     tmp_y = term(N/2);
			     if(max_y<tmp_y)
				     max_y=tmp_y;
			     dataout<<i/2<<" "<<tmp_y<<"\n";
			}
			
			cout<<"\nTemporary Graph data is written on the output file\n";
			dataout.close();
			
			N = N_tmp;
			N_fact = N_fact_tmp;
			
		}

};

void plotgraph(char *filename,char *graph_title)
{
		char filenm1[30];
          FILE *gnuplot;
		
		cout << "\nEnter Output \" .ps \" filename \n";
		cin >> filenm1;
		
		gnuplot = popen("gnuplot -persist","w");
		
		fprintf(gnuplot,"set terminal postscript\n");
		fprintf(gnuplot,"set output \"%s\"\n",filenm1);
		
		fprintf(gnuplot,"set origin 0.0,0.0; plot \"%s\" \
using 1: 2 title '%s' with lines ",filename,graph_title);
	     fflush(gnuplot);
			
		fclose(gnuplot);

}

int main()
{

     char filename[20];
	
	strcpy(filename,"../out/binomial_data.txt");

	char ch = 'y';
	float N, p;
	
	do
	{
		cout << "\n A : Plot graph with respect to n1 and N where n1 ranging from 0-N " ;
		cout << "\n B : Plot graph with respect to P(0) and N where P(0) is probability " ;
		cout << "\n     of zero displacement " ;
		cout << "\n C : Exit " ;
		cout << "\n Enter choice (A/B/C) : " ;
		cin >> ch;
		
		switch (ch)
		{
		case 'A' :
		case 'a' :
			{
			cout << "\n Enter Total Number Of Steps (i.e N) : " ;
			cin >> N;
			cout << "\n Enter the Probability of taking step to Right (i.e p) (0.1-0.9) : " ;
			cin >> p;

			binomial b1(N,p,1-p);
			b1.create_plot_file(filename);
			plotgraph(filename,"Binomial Distribution");
			
			break;
			}
		case 'B' :
		case 'b' :
			{
			cout << "\n Enter Factor of Increment in N : " ;
			cin >> N;
			
			binomial b1(20,0.5,0.5);
			b1.create_plot_p2N_file(N,filename);
			plotgraph(filename,"Graph For p(0) to N for p=0.5 q=0.5");
			
			break;
			}
		case 'C' :
		case 'c' :
			{
			ch = 'Y'; 
			break;
			}
		}
		
	}while( ch != 'Y' );
	
	return 0;
}